package cn.edu.scau.cmi.ema.service;

import cn.edu.scau.cmi.ema.base.CmiPagination;
import cn.edu.scau.cmi.ema.domain.*;
import cn.edu.scau.cmi.ema.service.base.CmiEmaService;
import cn.edu.scau.cmi.ema.util.CmiSqlUtil;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Query;
import java.util.*;
@Service("DetectdetailService")
@Transactional

public class DetectdetailServiceImpl extends CmiEmaService implements DetectdetailService {
	public DetectdetailServiceImpl() {
	}

	@Transactional
	public Detectdetail saveDetectdetail(Detectdetail detectdetail) {

		if (detectdetail.getId() == null) {
			Detect detect = detectDAO.findDetectById(detectdetail.getDetect().getId());
			Feature feature = featureDAO.findFeatureById(detectdetail.getFeature().getId());
			Unit unit = unitDAO.findUnitById(detectdetail.getUnit().getId());
			Detectmethod detectmethod = detectmethodDAO.findDetectmethodById(detectdetail.getDetectmethod().getId());

			Detectdetail existingDetectdetail = detectdetailDAO.findDetectdetailByPhysicalPrimaryKey(detect.getId(),
					feature.getId(), detectdetail.getValue(), unit.getId());

			detectdetail.setDetect(detect);
			detectdetail.setFeature(feature);
			detectdetail.setUnit(unit);
			detectdetail.setDetectmethod(detectmethod);

			if (isEquals(detectdetail, existingDetectdetail)) {
				return existingDetectdetail;
			}

			detectdetail = detectdetailDAO.store(detectdetail);
			detectdetailDAO.flush();

		} else {
			Detectdetail existingDetectdetail = detectdetailDAO.findDetectdetailByPrimaryKey(detectdetail.getId());

			detectdetail = detectdetailDAO.store(detectdetail);
			detectdetailDAO.flush();
		}

		return detectdetail;
	}

	public void deleteDetectdetail(Detectdetail detectdetail) {
		detectdetailDAO.remove(detectdetail);
		detectdetailDAO.flush();
	}

	@Transactional
	public void deleteDetectdetails(Set<Integer> deleteDetectdetailsId) {
		Query query = detectdetailDAO.createNamedQuery("deleteDetectdetailsById", -1, -1);
		query.setParameter(1, deleteDetectdetailsId);
		query.executeUpdate();
	}

	@Transactional
	public Set<Detectdetail> loadDetectdetails() {
		return detectdetailDAO.findAllDetectdetails();

	}

	@Transactional
	public Set<Detectdetail> loadReferenceDetectdetails(Set<Detectdetail> detectdetails) {
		Iterator<Detectdetail> detectdetailsIterator = detectdetails.iterator();
		Set<Detectdetail> referencedDetectdetails = new HashSet<>();
		while (detectdetailsIterator.hasNext()) {
			Detectdetail currentDetectdetail = detectdetailsIterator.next();

		}
		return referencedDetectdetails;
	}

	public Set<Detectdetail> loadDetectdetailsByIdSet(Set<Integer> detectdetailIdSet) {

		Iterator<Integer> detectdetailIdIterator = detectdetailIdSet.iterator();
		Set<Detectdetail> detectdetailSet = new HashSet<>();
		while (detectdetailIdIterator.hasNext()) {
			Integer id = detectdetailIdIterator.next();
			Detectdetail currentDetectdetail = detectdetailDAO.findDetectdetailById(id);
			detectdetailSet.add(currentDetectdetail);
		}
		return detectdetailSet;
	}

	@Transactional
	public List<Detectdetail> findAllDetectdetails(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Detectdetail>(detectdetailDAO.findAllDetectdetails(startResult, maxRows));
	}

	@Transactional
	public Detectdetail findDetectdetailByPrimaryKey(Integer id) {
		return detectdetailDAO.findDetectdetailByPrimaryKey(id);
	}

	@Transactional
	public Integer countDetectdetails() {
		return ((Long) detectdetailDAO.createQuerySingleResult("select count(o) from Detectdetail o").getSingleResult())
				.intValue();
	}

	@Transactional
	public Integer countDetectdetails(CmiPagination page) {
		String sql = CmiSqlUtil.createCountHql(page, Detectdetail.class);
		return ((Long) detectdetailDAO.createQuerySingleResult(sql).getSingleResult()).intValue();
	}

	/**
	 * search for name with ajax
	 *
	 */
	@Transactional
	public Integer countDetectdetailsByName(String queryName) {
		Query query = detectdetailDAO.createNamedQuery("countDetectdetailsByName", -1, -1);
		query.setParameter(1, queryName);
		return new Long((long) query.getSingleResult()).intValue();
	}

	@Transactional
	public Integer countDetectdetailsByDetachedCriteria(CmiPagination page) {
		DetachedCriteria detachedCriteria = CmiSqlUtil.createDetachedCriteria(page, Detectdetail.class);
		Session session = (Session) entityManager.getDelegate();
		detachedCriteria.setProjection(Projections.rowCount());
		return new Long((long) detachedCriteria.getExecutableCriteria(session).uniqueResult()).intValue();
	}

	public Map<String, ?> loadDetectdetailObjectReferencedSet(Detectdetail detectdetail) {
		HashMap<String, Object> objectReferencedSetMap = new HashMap<>();
		if (detectdetail.getDetect() != null) {

			Set<Integer> detectIds = new HashSet<Integer>();
			detectIds.add(detectdetail.getDetect().getId());
			objectReferencedSetMap.put("detectIds", detectIds);
		}
		if (detectdetail.getFeature() != null) {

			Set<Integer> featureIds = new HashSet<Integer>();
			featureIds.add(detectdetail.getFeature().getId());
			objectReferencedSetMap.put("featureIds", featureIds);
		}
		if (detectdetail.getUnit() != null) {

			Set<Integer> unitIds = new HashSet<Integer>();
			unitIds.add(detectdetail.getUnit().getId());
			objectReferencedSetMap.put("unitIds", unitIds);
		}
		if (detectdetail.getDetectmethod() != null) {

			Set<Integer> detectmethodIds = new HashSet<Integer>();
			detectmethodIds.add(detectdetail.getDetectmethod().getId());
			objectReferencedSetMap.put("detectmethodIds", detectmethodIds);
		}

		return objectReferencedSetMap;
	}

	public Map<String, ?> loadDetectdetailClassReferencedSet(Detectdetail detectdetail) {
		HashMap<String, Object> classReferencedSetMap = new HashMap<>();
		classReferencedSetMap.put("detects", detectDAO.findAllDetects());
		classReferencedSetMap.put("features", featureDAO.findAllFeatures());
		classReferencedSetMap.put("units", unitDAO.findAllUnits());
		classReferencedSetMap.put("detectmethods", detectmethodDAO.findAllDetectmethods());

		return classReferencedSetMap;
	}

	public boolean isEquals(Detectdetail detectdetail, Object obj) {
		if (obj == detectdetail)
			return true;
		if (!(obj instanceof Detectdetail))
			return false;
		Detectdetail comparedDetectdetail = (Detectdetail) obj;
		if (!CheckPropertyEqual(detectdetail.getDetect().getId(), comparedDetectdetail.getDetect().getId())) {
			return false;
		}
		if (!CheckPropertyEqual(detectdetail.getFeature().getId(), comparedDetectdetail.getFeature().getId())) {
			return false;
		}
		if (!CheckPropertyEqual(detectdetail.getValue(), comparedDetectdetail.getValue())) {
			return false;
		}
		if (!CheckPropertyEqual(detectdetail.getUnit().getId(), comparedDetectdetail.getUnit().getId())) {
			return false;
		}
		return true;
	}

	public static <T> boolean CheckPropertyEqual(T originProperty, T comparedProperty) {
		// 基本类型经过参数传递后会自动装箱
		String[] className = originProperty.getClass().getName().split("\\.");
		if (className[0].equals("java") && className[1].equals("math")) {
			return ((Comparable) originProperty).compareTo(comparedProperty) == 0 ? true : false;
		} else {
			return originProperty.equals(comparedProperty);
		}
	}
}

